﻿using System;
using System.Diagnostics;
using System.Threading;
using Rsdn.Janus.ObjectModel;

namespace Rsdn.Janus
{
    /// <summary>
    /// Осуществляет навигацию по форумам.
    /// </summary>
    public class ForumNavigator
    {
        private readonly MessageViewHistory _viewHistory = new MessageViewHistory();
        private readonly IServiceProvider _provider;

        private bool navigationMode;

        internal ForumNavigator(IServiceProvider provider)
        {
            _provider = provider;
            _viewHistory.MessageNavigate += HistoryNavigateFired;
        }

        /// <summary>
        /// История просмотра.
        /// </summary>
        public MessageViewHistory ViewHistory
        {
            get { return _viewHistory; }
        }


        /// <summary>
        /// Текущее состояние - режим навигации.
        /// </summary>
        public bool NavigationMode
        {
            get { return navigationMode; }
            private set { navigationMode = value; }
        }

        public event EventHandler MessageNavigated;

        /// <summary>
        /// Перейти на сообщение с указанным id.
        /// </summary>
        public bool SelectMessage(int msgId)
        {
            return SelectMessage(null, msgId, false);
        }

        /// <summary>
        /// Перейти на именованное сообщение.
        /// </summary>
        /// <param name="name">Имя сообщения.</param>
        /// <returns><c>true</c> - перейти удалось, иначе - <c>false</c>.</returns>
        public void SelectMessage(string name)
        {
            var found =
                DatabaseManager.GetMessageByName(
                    _provider,
                    name,
                    msg => new { msg.ID, msg.ForumID });

            if (found != null)
            {
                SelectMessage(found.ForumID, found.ID, false);
            }
        }

        /// <summary>
        /// Перейти на сообщение с указанным id в указанном форуме.
        /// </summary>
        /// <param name="forumId">The forum id.</param>
        /// <param name="msgId">The MSG id.</param>
        /// <param name="forceNavigation">if set to <c>true</c> [force navigate].</param>
        /// <returns></returns>
        public bool SelectMessage(int? forumId, int msgId, bool forceNavigation)
        {
#if SEL_TRACE
            Trace.WriteLine(string.Format("SEL:SelectMessage {0}.{1}", forumId, msgId));
            Trace.Flush();
#endif

            if (forumId == null)
            {
                forumId = DatabaseManager.FindMessageForumId(_provider, msgId);
            }

            if (forumId == null)
            {
                return false;
            }

            Forum forum = Forums.Instance[forumId.Value];

            if (forum == null)
            {
                return false;
            }

            IMsg msg = forum.FindMsgById(msgId);

            if (msg == null)
            {
                return false;
            }

            NavigationMode = true;

            try
            {
                forum.ActiveMsg = msg;

                // Refresh forum only if changed
                // and forum is active now
                IFeature activeFeature = Features.Instance.ActiveFeature;
                Forum activeForum = activeFeature as Forum;
#if SEL_TRACE
                Trace.WriteLine(
                    string.Format(
                        "SEL:ActiveFeature {0}, activeForum {1} new forum {2}", activeFeature, activeForum, forum));
                Trace.Flush();
#endif                
                if (forum != null)
                {
                    if (//activeFeature is Forum && // Note AN why we need it?
                        activeForum == null 
                        || (activeForum != null && forumId != activeForum.ID))
                    {
                        //Forums.Instance.ActiveForum = null;
                        //Forums.Instance.ActiveForum = forum;

                        Features.Instance.ActiveFeature = null;
#if SEL_TRACE
                        Trace.WriteLine(string.Format("SEL:Features.Instance.ActiveFeature {0}", forum));
                        Trace.Flush();
#endif
                        Features.Instance.ActiveFeature = forum;
                        forceNavigation = true;
                    }
                    //else if (forum != null && activeForum == null)
                    //{
                    //}
                }
                _viewHistory.Navigate(msg.ID, forceNavigation);
            }
            finally
            {
                NavigationMode = false;
            }

            return true;
        }

        private void HistoryNavigateFired(object sender, MessageNavigateEventArgs e)
        {
            if (!NavigationMode)
            {
                SelectMessage(_viewHistory.CurrentEntry.MessageId);
            }

            if (Forums.Instance.ActiveForum != null)
            {
                IMsg msg = Forums.Instance.ActiveForum.ActiveMsg;
                if (msg != null && msg.ID == e.MessageId)
                {
                    e.MessageSubject = msg.Subject;
                }
            }

            if (MessageNavigated != null)
            {
                MessageNavigated(this, EventArgs.Empty);
            }
        }
    }
}